package com.zx.sdk.league.member;

import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.kwad.sdk.api.KsAdSDK;
import com.kwad.sdk.api.KsFeedAd;
import com.kwad.sdk.api.KsInterstitialAd;
import com.kwad.sdk.api.KsLoadManager;
import com.kwad.sdk.api.KsRewardVideoAd;
import com.kwad.sdk.api.KsScene;
import com.kwad.sdk.api.KsSplashScreenAd;
import com.kwad.sdk.api.KsVideoPlayConfig;
import com.kwad.sdk.api.SdkConfig;
import com.kwad.sdk.api.model.AdExposureFailedReason;
import com.kwad.sdk.api.model.AdExposureFailureCode;
import com.zx.sdk.ZxSDK;
import com.zx.sdk.listener.BaseZxBannerListener;
import com.zx.sdk.listener.BaseZxRewardListener;
import com.zx.sdk.listener.BaseZxSplashListener;
import com.zx.sdk.model.AdInfo;
import com.zx.sdk.model.ReadyAdPosition;
import com.zx.sdk.model.ZxError;
import com.zx.sdk.util.CollectionHelper;
import com.zx.sdk.util.LogHelper;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class KS extends BaseLeagueMember<Object, Object, KsFeedAd, KsInterstitialAd, Object> {
    private BaseZxSplashListener listener;

    @Override
    public String getName() {
        return "ks";
    }

    @Override
    protected void onInit(Context context, String appId, boolean initialized) {
        KsAdSDK.init(ZxSDK.getContext(), new SdkConfig.Builder()
                .appId(appId) // 测试aapId，请联系快手平台申请正式AppId，必填
                .appName(ZxSDK.getAppName())  // 测试appName，请填写您应用的名称，
                .showNotification(true) // 是否展示下载通知栏
                .debug(ZxSDK.isDebug()) // 是否开启sdk 调试日志  可选
                .build());
    }

    @Override
    protected void onLoadSplash(AdInfo adInfo, ViewGroup container, String mode, String type, BaseZxSplashListener listener) {
        if (AdInfo.AD_TYPE_EXPRESS_INTERSTITIAL_AD == adInfo.getAdType()) {
            onLoadInterstitial((Activity) container.getContext(), adInfo, mode, type, new BaseZxRewardListener() {
                @Override
                public void onADClick() {
                    listener.onADClicked();
                }

                @Override
                public void onADClose() {
                    listener.onADDismissed();
                }

                @Override
                public void onADExpose() {
                    listener.onADExposure();
                }

                @Override
                public void onADLoad() {
                    listener.onADLoaded(0L);
                }

                @Override
                public void onReward(@NonNull Map<String, Object> map) {

                }

                @Override
                public void onVideoCached() {

                }

                @Override
                public void onVideoComplete() {

                }

                @Override
                public void onPreLoadADError(ZxError error) {
                    listener.onPreLoadNoAD(error);
                }

                @Override
                public void onRewardStepVerify(int taskType, int currentTaskStatus) {

                }

                @Override
                public void onAdSkip(float v) {

                }

                @Override
                public void onVideoPlayError(ZxError error) {
                }

                @Override
                public void onNoAD(ZxError error) {
                    listener.onNoAD(error);
                }

                @Override
                public void onPreloading() {
                    listener.onPreloading();
                }

                @Override
                public void onLoaded() {
                    listener.onLoaded();
                }
            });
            return;
        }
        this.listener = listener;
        Long pidLong = getFormatPid(adInfo.getMapPid());
        if (pidLong == null) return;
        KsScene scene = new KsScene.Builder(pidLong).build();
        KsLoadManager loadManager = KsAdSDK.getLoadManager();
        if (loadManager == null) {
            return;
        }
        loadManager.loadSplashScreenAd(scene, new KsLoadManager.SplashScreenAdListener() {
            @Override
            public void onError(int code, String msg) {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        listener.onPreLoadNoAD(KS.this, new ZxError(String.valueOf(code), msg), adInfo);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        listener.onNoAD(KS.this, new ZxError(String.valueOf(code), msg), adInfo);
                        break;
                }
            }

            @Override
            public void onRequestResult(int adNumber) {

            }

            @Override
            public void onSplashScreenAdLoad(KsSplashScreenAd splashScreenAd) {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        saveSplash(adInfo.getMapPid(), splashScreenAd, container);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        onShowSplash(adInfo, container, splashScreenAd, listener);
                        break;
                }
                listener.onADLoaded(KS.this, -1, adInfo);
            }
        });
    }

    @Override
    public boolean onShowSplash(AdInfo adInfo, ViewGroup container, @Nullable Object splash, BaseZxSplashListener listener) {
        if (splash instanceof KsSplashScreenAd) {
            container.addView(((KsSplashScreenAd) splash).getView(container.getContext(), new SplashScreenAdInteractionListener(this.listener, this, adInfo)));
            return true;
        } else if (splash instanceof KsInterstitialAd) {
            try {
                ((KsInterstitialAd) splash).showInterstitialAd((Activity) container.getContext(), new KsVideoPlayConfig.Builder().build());
                return true;
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }

    @Override
    public void onLoadReward(Activity context, AdInfo adInfo, String mode, String type, BaseZxRewardListener listener) {
        if (AdInfo.AD_TYPE_EXPRESS_INTERSTITIAL_AD == adInfo.getAdType()) {
            onLoadInterstitial(context, adInfo, mode, type, listener);
            return;
        }
        Long pidLong = getFormatPid(adInfo.getMapPid());
        if (pidLong == null) return;
        KsScene.Builder builder = new KsScene.Builder(pidLong);
        Map<String, String> rewardCallbackExtraData = new HashMap<>();
        rewardCallbackExtraData.put("thirdUserId", ZxSDK.getUid());
        rewardCallbackExtraData.put("extraData", new Gson().toJson(adInfo));
        builder.rewardCallbackExtraData(rewardCallbackExtraData);
        KsLoadManager loadManager = KsAdSDK.getLoadManager();
        if (loadManager == null) {
            return;
        }
        loadManager.loadRewardVideoAd(builder.build(), new KsLoadManager.RewardVideoAdListener() {
            @Override
            public void onError(int code, String msg) {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        listener.onPreLoadADError(KS.this, new ZxError(String.valueOf(code), msg), adInfo);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        listener.onNoAD(KS.this, new ZxError(String.valueOf(code), msg), adInfo);
                        break;
                }
            }

            @Override
            public void onRewardVideoResult(@Nullable List<KsRewardVideoAd> list) {

            }

            @Override
            public void onRewardVideoAdLoad(@Nullable List<KsRewardVideoAd> adList) {
                if (CollectionHelper.isEmpty(adList)) {
                    listener.onNoAD(KS.this, new ZxError("-1", "返回的广告列表为空"), adInfo);
                    return;
                }
                KsRewardVideoAd rewardVideoAd = adList.get(0);
                rewardVideoAd.setRewardAdInteractionListener(new KsRewardVideoAd.RewardAdInteractionListener() {
                    @Override
                    public void onAdClicked() {
                        listener.onADClick(KS.this, adInfo);
                    }

                    @Override
                    public void onPageDismiss() {
                        listener.onADClose(KS.this, adInfo);
                    }

                    @Override
                    public void onVideoSkipToEnd(long x) {

                    }

                    @Override
                    public void onVideoPlayError(int code, int extra) {
                        listener.onVideoPlayError(KS.this, new ZxError(String.valueOf(code), String.valueOf(extra)), adInfo);
                    }

                    @Override
                    public void onVideoPlayEnd() {
                        listener.onVideoComplete(KS.this, adInfo);
                    }

                    @Override
                    public void onVideoPlayStart() {
                        listener.onADExpose(KS.this, adInfo);
                    }

                    @Override
                    public void onRewardVerify() {
                        listener.onReward(KS.this, Collections.emptyMap(), adInfo);
                    }

                    @Override
                    public void onRewardStepVerify(int i, int i1) {
                        listener.onRewardStepVerify(KS.this, i, i1, adInfo);
                    }

                    @Override
                    public void onExtraRewardVerify(int i) {

                    }
                });
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        saveReward(adInfo.getMapPid(), rewardVideoAd);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        rewardVideoAd.showRewardVideoAd(context, new KsVideoPlayConfig.Builder().build());
                        break;
                }
                listener.onADLoad();
            }
        });
    }

    @Override
    public boolean onShowReward(Activity context, AdInfo adInfo, @Nullable Object reward, BaseZxRewardListener listener) {
        if (reward instanceof KsInterstitialAd && onShowInterstitial(context, adInfo, (KsInterstitialAd) reward, listener)) {
            return true;
        } else if (reward instanceof KsRewardVideoAd) {
            ((KsRewardVideoAd) reward).showRewardVideoAd(context, new KsVideoPlayConfig.Builder().build());
            return true;
        }
        return false;
    }

    @Override
    public void onLoadInterstitial(Activity context, AdInfo adInfo, String mode, String type, BaseZxRewardListener listener) {
        Long pidLong = getFormatPid(adInfo.getMapPid());
        if (pidLong == null) return;
        KsScene scene = new KsScene.Builder(pidLong).build();
        KsAdSDK.getLoadManager().loadInterstitialAd(scene, new KsLoadManager.InterstitialAdListener() {
            @Override
            public void onError(int i, String s) {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        listener.onPreLoadADError(KS.this, new ZxError(String.valueOf(i), s), adInfo);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        listener.onNoAD(KS.this, new ZxError(String.valueOf(i), s), adInfo);
                        break;
                }
            }

            @Override
            public void onRequestResult(int adNumber) {

            }

            @Override
            public void onInterstitialAdLoad(@Nullable List<KsInterstitialAd> adList) {
                listener.onADLoad(KS.this, adInfo);
                if (adList != null && adList.size() > 0) {
                    KsInterstitialAd mKsInterstitialAd = adList.get(0);
                    mKsInterstitialAd.setAdInteractionListener(new KsInterstitialAd.AdInteractionListener() {
                        @Override
                        public void onAdClicked() {
                            listener.onADClick(KS.this, adInfo);
                        }

                        @Override
                        public void onAdShow() {
                            listener.onADExpose(KS.this, adInfo);
                        }

                        @Override
                        public void onAdClosed() {

                        }

                        @Override
                        public void onPageDismiss() {
                            if (ZxSDK.REWARD.equals(adInfo.getDisplay())) {
                                Map<String, Object> map = new HashMap<>();
                                map.put("Id", adInfo.getMapPid());
                                listener.onReward(KS.this, map, adInfo);
                            }
                            listener.onADClose(KS.this, adInfo);
                        }

                        @Override
                        public void onVideoPlayError(int i, int i1) {
                            listener.onVideoPlayError(KS.this, new ZxError(String.valueOf(i), String.valueOf(i1)), adInfo);
                        }

                        @Override
                        public void onVideoPlayEnd() {

                        }

                        @Override
                        public void onVideoPlayStart() {

                        }

                        @Override
                        public void onSkippedAd() {

                        }
                    });
                    switch (mode) {
                        case ZxSDK.FETCH_ONLY:
                            if (ZxSDK.SPLASH.equals(adInfo.getDisplay())) {
                                saveSplash(adInfo.getMapPid(), mKsInterstitialAd, null);
                            } else if (ZxSDK.REWARD.equals(adInfo.getDisplay())) {
                                saveReward(adInfo.getMapPid(), mKsInterstitialAd);
                            } else if (ZxSDK.INTERSTITIAL.equals(adInfo.getDisplay())) {
                                saveInterstitial(adInfo.getMapPid(), mKsInterstitialAd);
                            }
                            break;
                        case ZxSDK.FETCH_AND_SHOW:
                            mKsInterstitialAd.showInterstitialAd(context, new KsVideoPlayConfig.Builder().build());
                            break;
                    }
                }
            }
        });
    }

    @Override
    public boolean onShowInterstitial(Activity context, AdInfo adInfo, @Nullable KsInterstitialAd interstitial, BaseZxRewardListener listener) {
        try {
            interstitial.showInterstitialAd(context, new KsVideoPlayConfig.Builder().build());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static class SplashScreenAdInteractionListener implements KsSplashScreenAd.SplashScreenAdInteractionListener {

        private BaseZxSplashListener listener;
        private KS ks;
        private AdInfo adInfo;

        public SplashScreenAdInteractionListener(BaseZxSplashListener listener, KS ks, AdInfo adInfo) {
            this.listener = listener;
            this.ks = ks;
            this.adInfo = adInfo;
        }

        @Override
        public void onAdClicked() {
            listener.onADClicked(ks, adInfo);
        }

        @Override
        public void onAdShowError(int code, String msg) {
            listener.onNoAD(ks, new ZxError(String.valueOf(code), msg), adInfo);
        }

        @Override
        public void onAdShowEnd() {
            listener.onADDismissed(ks, adInfo);
        }

        @Override
        public void onAdShowStart() {
            listener.onADExposure(ks, adInfo);
        }

        @Override
        public void onSkippedAd() {
            listener.onADDismissed(ks, adInfo);
        }

        @Override
        public void onDownloadTipsDialogShow() {
            listener.onDownloadTipsDialogShow(ks, adInfo);
        }

        @Override
        public void onDownloadTipsDialogDismiss() {
            listener.onDownloadTipsDialogDismiss(ks, adInfo);
        }

        @Override
        public void onDownloadTipsDialogCancel() {
            listener.onDownloadTipsDialogCancel(ks, adInfo);
        }
    }

    @Override
    public void onLoadBanner(Activity context, ViewGroup container, AdInfo adInfo, String mode, String type, BaseZxBannerListener listener) {
        Long pidLong = getFormatPid(adInfo.getMapPid());
        if (pidLong == null) return;
        KsScene scene = new KsScene.Builder(pidLong).adNum(1).build();
        KsAdSDK.getLoadManager().loadConfigFeedAd(scene, new KsLoadManager.FeedAdListener() {
            @Override
            public void onError(int code, String msg) {
                listener.onAdFailed(new ZxError(String.valueOf(code), msg), KS.this, adInfo);
            }

            @Override
            public void onFeedAdLoad(@Nullable List<KsFeedAd> adList) {
                if (adList == null || adList.isEmpty()) {
                    listener.onAdFailed(new ZxError("-1", "adList.isEmpty"), KS.this, adInfo);
                    return;
                }
                KsFeedAd ksFeedAd = adList.get(0);
                if (ksFeedAd == null) {
                    listener.onAdFailed(new ZxError("-1", "ksFeedAd == null"), KS.this, adInfo);
                    return;
                }
                ksFeedAd.setAdInteractionListener(new KsFeedAd.AdInteractionListener() {
                    @Override
                    public void onAdClicked() {
                        listener.onAdClick(null, KS.this, adInfo);
                    }

                    @Override
                    public void onAdShow() {
                        listener.onAdShow(null, KS.this, adInfo);
                        addCloseBtnToBanner(container, () -> dismissBanner(container, ksFeedAd));
                    }

                    @Override
                    public void onDislikeClicked() {
                        listener.onAdClose(null, KS.this, adInfo);
                        dismissBanner(container, ksFeedAd);
                    }

                    @Override
                    public void onDownloadTipsDialogShow() {

                    }

                    @Override
                    public void onDownloadTipsDialogDismiss() {

                    }
                });
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        saveBanner(adInfo.getMapPid(), ksFeedAd);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        onShowBanner(context, adInfo, container, ksFeedAd, listener);
                        break;
                }
            }
        });
    }

    @Override
    public boolean onShowBanner(Activity activity, AdInfo adInfo, ViewGroup container, KsFeedAd banner, BaseZxBannerListener listener) {
        container.removeAllViews();
        View videoView = banner.getFeedView(activity);
        if (videoView != null && videoView.getParent() == null) {
            container.addView(videoView);
            addCloseBtnToBanner(container, () -> dismissBanner(container));
            return true;
        }
        return false;
    }

    private void dismissBanner(ViewGroup container) {
        container.removeAllViews();
    }
    private void dismissBanner(ViewGroup container, KsFeedAd adView) {
        container.removeAllViews();
    }

    @Override
    public boolean isPreResReady(String type, String pid) {
        Object filledRewardByPid = getFilledRewardByPid(pid);
        if (filledRewardByPid instanceof KsRewardVideoAd) {
            return ((KsRewardVideoAd) filledRewardByPid).isAdEnable();
        }
        return super.isPreResReady(type, pid);
    }

    private Long getFormatPid(String pid) {
        try {
            return Long.parseLong(pid);
        } catch (Exception e) {
            LogHelper.e("KS getFormatPid", e);
            return null;
        }
    }

    /**
     * 获取 cpm | 单位=分
     *
     * @return -1=为加载到资源
     */
    @Override
    public int getCpmByPid(String type, String pid) {
        int cpm = super.getCpmByPid(type, pid);
        try {
            switch (type) {
                case ZxSDK.SPLASH:
                    if (splashMap.containsKey(pid)) {
                        Object adv = splashMap.get(pid);
                        if (adv instanceof KsSplashScreenAd) {
                            cpm = ((KsSplashScreenAd) adv).getECPM();
                        } else if (adv instanceof KsRewardVideoAd) {
                            cpm = ((KsRewardVideoAd) adv).getECPM();
                        } else if (adv instanceof KsInterstitialAd) {
                            cpm = ((KsInterstitialAd) adv).getECPM();
                        }
                    }
                case ZxSDK.REWARD:
                    if (rewardMap.containsKey(pid)) {
                        Object adv = rewardMap.get(pid);
                        if (adv instanceof KsSplashScreenAd) {
                            cpm = ((KsSplashScreenAd) adv).getECPM();
                        } else if (adv instanceof KsRewardVideoAd) {
                            cpm = ((KsRewardVideoAd) adv).getECPM();
                        } else if (adv instanceof KsInterstitialAd) {
                            cpm = ((KsInterstitialAd) adv).getECPM();
                        }
                    }
                case ZxSDK.INTERSTITIAL:
                    if (interstitialMap.containsKey(pid)) {
                        cpm = interstitialMap.get(pid).getECPM();
                    }
                case ZxSDK.BANNER:
                    if (bannerMap.containsKey(pid)) {
                        cpm = bannerMap.get(pid).getECPM();
                    }
            }
        } catch (Exception exception) {
            LogHelper.d("KS getCpmByPid exception " + exception.getMessage());
        }
        cpmCache.put(type + pid, cpm);
        return cpm;
    }

    @Override
    public void notifyBiddingWin(String type, String mapPid, @Nullable ReadyAdPosition loser) {
        int cpm = getCpmByPid(type, mapPid);
        if (ZxSDK.SPLASH.equals(type)) {
            Object adv = splashMap.get(mapPid);
            if (adv instanceof KsRewardVideoAd) {
                ((KsRewardVideoAd) adv).setBidEcpm(cpm);
            } else if (adv instanceof KsSplashScreenAd) {
                ((KsSplashScreenAd) adv).setBidEcpm(cpm);
            } else if (adv instanceof KsInterstitialAd) {
                ((KsInterstitialAd) adv).setBidEcpm(cpm);
            }
        } else if (ZxSDK.REWARD.equals(type)) {
            Object adv = rewardMap.get(mapPid);
            if (adv instanceof KsRewardVideoAd) {
                ((KsRewardVideoAd) adv).setBidEcpm(cpm);
            } else if (adv instanceof KsSplashScreenAd) {
                ((KsSplashScreenAd) adv).setBidEcpm(cpm);
            } else if (adv instanceof KsInterstitialAd) {
                ((KsInterstitialAd) adv).setBidEcpm(cpm);
            }
        } else if (ZxSDK.INTERSTITIAL.equals(type)) {
            KsInterstitialAd adv = interstitialMap.get(mapPid);
            if (adv != null) {
                adv.setBidEcpm(cpm);
            }
        } else if (ZxSDK.BANNER.equals(type)) {
            KsFeedAd adv = bannerMap.get(mapPid);
            if (adv != null) {
                adv.setBidEcpm(cpm);
            }
        }
        LogHelper.d(getName(), "notifyBiddingWin", mapPid, "selfPrice =" + getCpmByPid(type, mapPid), "LoserPrice = " + (loser != null ? loser.getCpm() : 0));
    }

    @Override
    public void notifyBiddingLose(String type, String mapPid, ReadyAdPosition winner, ZxSDK.LoseReason reason) {
        AdExposureFailedReason adExposureFailedReason = new AdExposureFailedReason();
        adExposureFailedReason.winEcpm = winner.getCpm();
        if (ZxSDK.SPLASH.equals(type)) {
            Object adv = splashMap.get(mapPid);
            if (adv instanceof KsRewardVideoAd) {
                ((KsRewardVideoAd) adv).reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            } else if (adv instanceof KsSplashScreenAd) {
                ((KsSplashScreenAd) adv).reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            } else if (adv instanceof KsInterstitialAd) {
                ((KsInterstitialAd) adv).reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            }
        } else if (ZxSDK.REWARD.equals(type)) {
            Object adv = rewardMap.get(mapPid);
            if (adv instanceof KsRewardVideoAd) {
                ((KsRewardVideoAd) adv).reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            } else if (adv instanceof KsSplashScreenAd) {
                ((KsSplashScreenAd) adv).reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            } else if (adv instanceof KsInterstitialAd) {
                ((KsInterstitialAd) adv).reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            }
        } else if (ZxSDK.INTERSTITIAL.equals(type)) {
            KsInterstitialAd adv = interstitialMap.get(mapPid);
            if (adv != null) {
                adv.reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            }
        } else if (ZxSDK.BANNER.equals(type)) {
            KsFeedAd adv = bannerMap.get(mapPid);
            if (adv != null) {
                adv.reportAdExposureFailed(AdExposureFailureCode.BID_FAILED, adExposureFailedReason);
            }
        }
        LogHelper.d(getName(), "notifyBiddingLose", mapPid, "selfPrice =" + getCpmByPid(type, mapPid), "WinnerPrice = " + winner.getCpm());
    }
}
